Systematic literature review

Analysis of references

Authors
Affiliation

Olivier Caron

Paris Dauphine - PSL

Christophe Benavent

Paris Dauphine - PSL

Published

August 31, 2023

1 Libraries and loading data

Code
library(reactable)
library(tidyverse)
library(networkD3)
library(reactablefmtr)

list_articles <- read.csv2("nlp_full_data_final_18-08-2023.csv", encoding = "UTF-8") %>%
  rename("entry_number" = 1)
list_references <- read.csv2("nlp_references_final_18-08-2023.csv", encoding = "UTF-8") %>%
  rename("citing_art" = 1)
1colnames(list_articles) <- gsub("\\.+", "_", colnames(list_articles))
2colnames(list_articles) <- gsub("^[[:punct:]]+|[[:punct:]]+$", "", colnames(list_articles))
colnames(list_references) <- gsub("\\.+", "_", colnames(list_references))
colnames(list_references) <- gsub("^[[:punct:]]+|[[:punct:]]+$", "", colnames(list_references))
1
We replace the dots by one single underscore in the column names. It’s easier to manipulate.
2
We delete the punctuation marks in the beginning and end of the column names.

2 Co-authorship network of NLP marketing papers

Here, we manipulate our data to create a simple network using the networkD3 package. You can read the official CRAN Documentation here.

Code
authors <- list_articles %>%
  #filter(citedby_count > 10) %>%
  filter(subtypeDescription != "Erratum") %>%
1  filter(marketing == 1) %>%
  select(entry_number, authname)

# get unique entry numbers
entry_numbers <- unique(authors$entry_number)

# create empty data frame with two columns "from" and "to"
pairs_df <- data.frame(from = character(), 
                       to = character())

# loop through each entry number and get all combinations of pairs of names two by two
for (i in 1:length(entry_numbers)) 
  {
    entry_num <- entry_numbers[i]
    names <- unique(authors$authname[authors$entry_number == entry_num])
    if (length(names) > 1) #we can't use combn(name, 2) for solo authors, hence the if condition
      {
        pairs <- combn(names, 2)
        pairs_df <- rbind(pairs_df, data.frame(from = pairs[1,], to = pairs[2,]))
      } 
    else #if there is only one author, we just add his name to both "from" and "to" columns: he appears in the graph as a solo node. 
      #It's sad but at least he's there
      {
        pairs_df <- rbind(pairs_df, data.frame(from = names, to = names))
      }
}

graph_collab_authors <- simpleNetwork(pairs_df,
        Source       = 1,           # column number of source
        Target       = 2,           # column number of target
        linkDistance = 50,          # distance between node. Increase this value to have more space between nodes
        charge       = -15,         # numeric value indicating either the strength of the node repulsion (negative value) or attraction (positive value)
        fontSize     = 14,          # size of the node names
        fontFamily   = "serif",     # font og node names
        linkColour   = "#666",       # colour of edges, MUST be a common colour for the whole graph
        nodeColour   = "#69b3a2",    # colour of nodes, MUST be a common colour for the whole graph
        opacity      = 0.9,         # opacity of nodes. 0=transparent. 1=no transparency
        zoom         = T            # Can you zoom on the figure?
        )

graph_collab_authors

# save the widget
htmlwidgets::saveWidget(graph_collab_authors,"graph_collab_authors.html")
readr::write_excel_csv2(pairs_df,"pairs_df.csv")
1
We have an interest only in articles related to marketing because there are a lot of conferences or papers related to purely technical matters that have “consumer” in the source title.

The figure below is a network that shows co-authors connections. This is an undirected graph.

Code
authors_articles <- list_articles %>%
  filter(subtypeDescription != "Erratum") %>%
  filter(marketing == 1) %>%
  select(authname, prism_coverDate, dc_title, citedby_count) %>%
  arrange(authname)


reactable(authors_articles, striped = TRUE, filterable = TRUE, defaultPageSize = 5,
          columns = list(
          authname = colDef(name = "Name", minWidth = 40, align = "center"),
          prism_coverDate = colDef(name = "Date", minWidth = 40, align = "center"),
          dc_title = colDef(name = "Article Title", minWidth = 200, align = "center"),
          citedby_count = colDef(name = "Citations", minWidth = 30, align = "center"))
)

3 Network of references

Here, we want to get an overview of important articles in the field of marketing using NLP methods. To do so, we construct the same network as before but analyzing references. The type of publication we consider here is noted on the right

Since the rendering with all the references (27710) would be to hard to render on this html page, we filter by the 500 most cited references.

Code
references_df <- list_references %>%
  slice_max(citedby_count, n = 500) %>%
  select(citing_art, scopus_eid) %>%
  mutate(citing_art = str_sub(citing_art,11)) %>%
  mutate(scopus_eid = str_sub(scopus_eid,8))
  


references_graph <- simpleNetwork(references_df,
        Source       = 1,                 # column number of source
        Target       = 2,                 # column number of target
        linkDistance = 30,          # distance between node. Increase this value to have more space between nodes
        charge       = -100,                # numeric value indicating either the strength of the node repulsion (negative value) or attraction (positive value)
        fontSize     = 14,               # size of the node names
        fontFamily   = "serif",       # font og node names
        #linkColour  = "#666",        # colour of edges, MUST be a common colour for the whole graph
        #nodeColour  = "#black",     # colour of nodes, MUST be a common colour for the whole graph
        opacity      = 1,              # opacity of nodes. 0=transparent. 1=no transparency
        zoom         = T                   # Can you zoom on the figure?
        )
references_graph
Code
# save the widget

#htmlwidgets::saveWidget(graph_collab_authors,"graph_collab_authors.html")
readr::write_excel_csv2(references_df,"references_df.csv")
Code
references_reactable <- list_references %>%
  distinct(scopus_eid)

references_reactable <- list_references %>%
  distinct(scopus_eid, .keep_all = TRUE) %>%
  select(scopus_eid, author_list_author_preferred_name_ce_indexed_name, prism_coverDate, title, sourcetitle, citedby_count) %>%
  mutate(scopus_eid = str_sub(scopus_eid,8))

reactable(
  references_reactable,
  striped = TRUE,
  filterable = TRUE,
  defaultPageSize = 5,
  columns = list(
    scopus_eid = colDef(name = "Ref ID", minWidth = 40, align = "center"),
    author_list_author_preferred_name_ce_indexed_name = colDef(name = "Author", minWidth = 60, align = "center"),
    prism_coverDate = colDef(name = "Date", minWidth = 40, align = "center"),
    title = colDef(name = "Title", minWidth = 100, align = "center"),
    sourcetitle = colDef(name = "Journal", minWidth = 70, align = "center"),
    citedby_count = colDef(name = "Citations", minWidth = 30, align = "center")
  )
)
Code
data_network_references <- list_references %>%
  mutate("auth" = ifelse(
    is.na(prism_coverDate) | prism_coverDate == "", 
    author_list_author_ce_indexed_name, 
    paste(author_list_author_ce_indexed_name, substr(prism_coverDate, 1, 4))
  )) %>%
  select(citing_art, scopus_eid, auth, prism_coverDate, sourcetitle, title, citedby_count) %>%
  mutate(citing_art = str_sub(citing_art,11)) %>%
  mutate(scopus_eid = str_sub(scopus_eid,8))

readr::write_excel_csv2(data_network_references,"data_network_references.csv")
Code
topref <- data_network_references %>%
  group_by(scopus_eid) %>%
  reframe(n=n(),
          auth,
          title,
          sourcetitle,
          citedby_count) %>%
  distinct(scopus_eid, .keep_all = TRUE) %>%
  arrange(desc(n))

reactable(
  topref,
  striped = TRUE,
  filterable = TRUE,
  defaultPageSize = 5,
  columns = list(
    n = colDef(name = "n", minWidth = 40, align = "center"),
    auth = colDef(name = "Author", minWidth = 60, align = "center"),
    scopus_eid = colDef(name = "Ref ID", minWidth = 40, align = "center"),
    title = colDef(name = "Title", minWidth = 100, align = "center"),
    sourcetitle = colDef(name = "Journal", minWidth = 70, align = "center"),
    citedby_count = colDef(name = "Citations", minWidth = 30, align = "center")
  )
) %>%
  add_title("List of references sorted by n")

List of references sorted by n

It appears that most of the references in the systematic review articles come from the field of marketing, with the exception of Blei’s article on the LDA algorithm.